package com.apache.uct.common.filter;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.apache.api.vo.ResultMsg;
import com.apache.passport.common.PassportHelper;
import net.sf.json.JSONObject;
import org.apache.log4j.Logger;

import com.apache.license.filter.AbstractFilter;
import com.apache.passport.common.XmlWhiteUtils;
import com.apache.security.util.SecurityHttpServletRequest;
import com.apache.security.util.SecurityHttpServletResponse;
import com.apache.tools.StrUtil;
import com.apache.uct.common.LoginUser;
import com.apache.uct.common.ToolsUtil;
import com.apache.uct.common.entity.Act;

public abstract class UctSupperFilter extends AbstractFilter {

	private Logger logger = Logger.getLogger(UctSupperFilter.class);

	protected Map<String, ArrayList<String>> whiteMap = new HashMap<String, ArrayList<String>>();

	protected String sysCode = "";

	protected boolean isOpenSecurityFilter = false;//是否开启安全过滤

	// \b 是单词边界(连着的两个(字母字符 与 非字母字符) 之间的逻辑上的间隔),
	// 字符串在编译时会被转码一次,所以是 "\\b"
	// \B 是单词内部逻辑间隔(连着的两个字母字符之间的逻辑上的间隔)
	private static String phoneReg = "\\b(ip(hone|od)|android|opera m(ob|in)i" + "|windows (phone|ce)|blackberry"
			+ "|s(ymbian|eries60|amsung)|p(laybook|alm|rofile/midp" + "|laystation portable)|nokia|fennec|htc[-_]"
			+ "|mobile|up.browser|[1-4][0-9]{2}x[1-4][0-9]{2})\\b";

	private static String tableReg = "\\b(ipad|tablet|(Nexus 7)|up.browser" + "|[1-4][0-9]{2}x[1-4][0-9]{2})\\b";

	// 移动设备正则匹配：手机端、平板
	private static Pattern phonePat = Pattern.compile(phoneReg, Pattern.CASE_INSENSITIVE);

	private static Pattern tablePat = Pattern.compile(tableReg, Pattern.CASE_INSENSITIVE);

	/**
	 * 检测是否是移动设备访问
	 *
	 * @param userAgent 浏览器标识
	 * @return true:移动设备接入，false:pc端接入
	 */
	protected boolean check(String userAgent) {
		if (null == userAgent) {
			userAgent = "";
		}
		// 匹配
		Matcher matcherPhone = phonePat.matcher(userAgent);
		Matcher matcherTable = tablePat.matcher(userAgent);
		if (matcherPhone.find() || matcherTable.find()) {
			return true;
		} else {
			return false;
		}
	}

	protected boolean canAccessSupper(LoginUser loginUser, String path) {
		boolean mark = false;
		Map<String, Act> acts = loginUser.getActMap();
		logger.info(acts);
		if (null != acts && !acts.isEmpty()) {
			for (String key : acts.keySet()) {
				Act act = acts.get(key);
				if (StrUtil.isNotNull(act.getActUrl())) {
					String str[] = act.getActUrl().split(",");
					for (int i = 0; i < str.length; i++) {
						if (str[i].endsWith(".action")) {
							if (path.equals(str[i]))
								return true;
						} else if (path.startsWith(str[i])) {
							return true;
						}
					}
				}
			}
		}
		return mark;
	}

	protected boolean JudgeIsMoblie(HttpServletRequest request) {
		boolean isMoblie = false;
		String mobileType = request.getParameter("userAgent");
		String randCode = request.getParameter("userKeys");
		if (StrUtil.isNotNull(mobileType) || StrUtil.isNotNull(randCode)) {
			return true;
		}

		if (request.getHeader("User-Agent") != null) {
			String dd = request.getHeader("User-Agent");
			isMoblie = check(dd);
		}
		return isMoblie;
	}

	protected boolean jkWhite(String servletPath){
		List<String> whiteJK= PassportHelper.whiteJK;
		for (int i = 0; i < whiteJK.size(); i++) {
			String wurl = whiteJK.get(i);
			if (servletPath.startsWith(wurl)) {
				return true;
			}
		}
		return false;
	}

	protected boolean unlockPath(String path, String sysCode) {
		XmlWhiteUtils.getInstance().deWhiteXml(whiteMap, sysCode);
		ArrayList<String> whiteUrl = (ArrayList<String>) whiteMap.get("whiteUrl");
		ArrayList<String> whiteParadigm = (ArrayList<String>) whiteMap.get("whiteParadigm");
		int wp = whiteParadigm.size();
		if (path.length() > 1) {
			if (whiteUrl.contains(path)) {
				return true;
			}
			for (int i = 0; i < wp; i++) {
				if ((whiteParadigm.get(i)).contains("*")) {
					String wdir = (whiteParadigm.get(i)).replace("*", "");
					int s = path.indexOf(wdir);
					if (s == 0) {
						return true;
					}
				} else if (!"".equals(whiteParadigm.get(i))) {
					int s = path.indexOf(whiteParadigm.get(i));
					if (s == 0) {
						return true;
					}
				}
			}
		}
		return false;
	}

	/**
	 * 清空系统信息
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	protected void clearLoginInfo(HttpServletRequest req, HttpServletResponse resp) {
		LoginUser loginUser = (LoginUser) req.getSession().getAttribute("loginUser");
		if (null == loginUser)
			return;
		Cookie[] cookies = req.getCookies();
		try {
			for (int i = 0; i < cookies.length; i++) {
				Cookie cookie = new Cookie(cookies[i].getName(), null);
				cookie.setMaxAge(0);
				cookie.setPath("/");//根据你创建cookie的路径进行填写
				resp.addCookie(cookie);
			}
		} catch (Exception ex) {
		}
		ArrayList lst = new ArrayList();
		Enumeration enumer = req.getSession().getAttributeNames();
		while (enumer.hasMoreElements()) {
			lst.add(enumer.nextElement());
		}
		for (int i = 0; i < lst.size(); i++) {
			req.getSession().removeAttribute(lst.get(i).toString());
		}
	}

	protected void gotoPage(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
			throws IOException, ServletException {
		if ("true".equalsIgnoreCase(ToolsUtil.getInstance().getValueByKey("is_open_security_filter"))) {//是否开启安全过滤
			filterChain.doFilter(new SecurityHttpServletRequest(request), new SecurityHttpServletResponse(response));
		} else {
			filterChain.doFilter(request, response);
		}
	}

	/**
	 * description:  跳到登录页面
	 */
	protected void gotoLogin(HttpServletRequest request, HttpServletResponse response, String msg)
			throws IOException {
		ResultMsg rmsg = new ResultMsg("F", StrUtil.doNull(msg, "您还没有登录，请您先登录再进行相应操作"));
		JSONObject array = JSONObject.fromObject(rmsg);
		this.outputJson(array.toString(), response, request.getParameter("callback"));
	}

	/**
	 * 输出json数据
	 */
	protected void outputJson(String json, HttpServletResponse response, String callback)
			throws IOException {
		if (StrUtil.isNotNull(json)) {
			PrintWriter out = response.getWriter();
			if (StrUtil.isNull(callback)) {
				response.setContentType("text/html;charset=UTF-8");
				response.setHeader("Access-Control-Allow-Origin", "*");
				response.setHeader("Access-Control-Allow-Methods", "POST,GET");
				response.setHeader("Access-Control-Allow-Credentials", "true");
				out.print(json);
			} else {
				response.setContentType("application/javascript");
				out.print(callback + "(" + json + ")");
			}
			out.flush();
			out.close();
		}
	}
}
